home *** CD-ROM | disk | FTP | other *** search
- #include "b&w.h"
- #include "image.h"
- #include <string.h>
- #include "patterns.h"
-
- inline int bw_pix(int color, int x, int y) // Transform color pix
- { // to B/W using pattern
- int sx = x % 8; // We suppose that 1st
- int sy = y % 8; // 16 patterns approxi-
- return (pattern[color][sy]) & (1 << sx) ? 1 : 0; // mates 16 colors
- }
- ////////////////////////
- int pcx_dump(imageP image, uchar* new_image, int nplanes)
- {
- int x; int count = 1;
- int bplin = ((image->xmax + 7) / 8);
- x = (nplanes - 1) * bplin; // start of last plane
- int shift = 2 * bplin;
- int c = 0;
-
- unsigned char ch = image->data[x];
-
- while(1)
- {
- x++;
- if(!(x % bplin)) // end of scan line or end of plane
- {
- if(x != bplin) // not the end of scan line
- x -= shift;
- else // end of scan line
- {
- if(count > 1 || (0xC0 == (0xC0 & ch)))
- new_image[c++] = (count | 128 | 64);
- new_image[c++] = ch;
- break;
- }
- }
-
- if(ch == image->data[x])
- {
- if(count == 63)
- {
- if(count > 1 || (0xC0 == (0xC0 & ch)))
- new_image[c++] = (count | 128 | 64);
- new_image[c++] = ch; // Write pattern
-
- count = 1;
- }
- else
- count++;
- }
- else
- {
- if(count > 1 || (0xC0 == (0xC0 & ch)))
- new_image[c++] = (count | 128 | 64);
- new_image[c++] = ch; // Write pattern
-
- count = 1;
- ch = image->data[x];
- }
- }
- return c;
- }
- //////////////////////////
- void dither_image(imageP image, int y)
- {
- int xmax = image->xmax + 1;
- for(int x = 0; x < xmax; x++)
- image_put_pixel(image, loc(x, 0),
- (bw_pix((uchar)(
- image_get_pixel(image, loc(x, 0), 1, N_PLANES)),
- x, y) ? 0 : 1), 1, 1);
- }
- //////////////////////////
- int pcx_col_to_bw(char* src_name, char* dest_name)
- {
- if(!strcmp(dest_name, src_name))
- return 0;
- FILE* f = fopen(src_name, "rb");
-
- if(f == NULL)
- {
- fclose(f);
- return 0;
- }
- FILE* f1 = fopen(dest_name, "wb");
-
- pcxheader p;
- pcxstream pcxF(f);
- get_pcx_header(&pcxF, &p);
- /* The following variable is absolutely unnecessary. But Paintbrush use
- 16-bit rounded files - I don't know why. Use old_bplin for compatibility.
- */
- int old_bplin = p.bplin;
- int np = p.nplanes;
- put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 1);
- p.nplanes = np;
-
- imageP image = (imageP)malloc(old_bplin/*p.bplin*/ * p.nplanes + sizeof(imageType));
- char* new_image = new uchar[p.bplin * p.nplanes];
-
- image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
- image->ymax = 0;
-
- int x; int y = 0; int count;
- int plane;
-
- plane = x = (p.nplanes - 1) * p.bplin; // start of last plane
- int height = p.y2 - p.y1 + 1;
- int height1;
- int shift = 2 * p.bplin;
- while(y <= height)
- {
- unsigned char ch = pcxF.get(); // read char
- if((ch & 0xC0 )==0xC0) // if two upper bits == 1
- {
- count = 63 & ch; // use 6 low bits as counter
- ch = pcxF.get();
- for(int j = 0; j < count; j++)
- {
- image->data[x] = ch;
- x++;
- if(x == old_bplin)//p.bplin)
- {
- dither_image(image, y);
- int len = pcx_dump(image, new_image, 1);
- fwrite(new_image, len, 1, f1);
-
- x = plane;
- y++;
- }
- else
- if(!(x % old_bplin))//p.bplin))
- x -= shift;
- }
- }
- else
- {
- (unsigned char)(image->data[x]) = ch;
- x++;
- if(x == old_bplin)//p.bplin)
- {
- dither_image(image, y);
- int len = pcx_dump(image, new_image, 1);
- fwrite(new_image, len, 1, f1);
- x = plane;
- y++;
- }
- else
- if(!(x % old_bplin))//p.bplin))
- x -= shift;
-
- }
- }
- delete image;
- delete new_image;
- fclose(f);
- fclose(f1);
- return 1;
- }
-
- //////////////////////////
- int pcx_bw_to_col(char* src_name, char* dest_name)
- {
- if(!strcmp(dest_name, src_name))
- return 0;
- FILE* f = fopen(src_name, "rb");
-
- if(f == NULL)
- {
- fclose(f);
- return 0;
- }
-
- pcxheader p;
- pcxstream pcxF(f);
- get_pcx_header(&pcxF, &p);
- /* The following variable is absolutely unnecessary. But Paintbrush use
- 16-bit rounded files - I don't know why. Use old_bplin for compatibility.
- */
- int old_bplin = p.bplin;
- if(p.bitpx == 1 && p.nplanes == N_PLANES)
- {
- fclose(f);
- return 0;
- }
- FILE* f1 = fopen(dest_name, "wb");
- int np = p.nplanes;
- put_pcx_header(f1, &p, loc(p.x2 - p.x1 + 1, p.y2 - p.y1 + 1), 1, 4);
- p.nplanes = np;
-
- imageP image = (imageP)malloc(p.bplin * p.nplanes + sizeof(imageType));
- char* new_image = new uchar[p.bplin * p.nplanes];
-
- image->xmax = (p.x2 - p.x1 + 1 + 7) / 8 * 8 - 1;
- image->ymax = 0;
-
- int x; int y = 0; int count;
- int plane;
-
- plane = x = (p.nplanes - 1) * p.bplin; // start of last plane
- int height = p.y2 - p.y1 + 1;
- int height1;
- int shift = 2 * p.bplin;
- while(y <= height)
- {
- unsigned char ch = pcxF.get(); // read char
- if((ch & 0xC0 )==0xC0) // if two upper bits == 1
- {
- count = 63 & ch; // use 6 low bits as counter
- ch = pcxF.get();
- for(int j = 0; j < count; j++)
- {
- image->data[x] = ch;
- x++;
- if(x == old_bplin)//p.bplin)
- {
- int len = pcx_dump(image, new_image, 1);
- for(int t = 0; t < N_PLANES; t++)
- {
- fwrite(new_image, len, 1, f1);
- }
- x = plane;
- y++;
- }
- else
- if(!(x % old_bplin))//p.bplin))
- x -= shift;
- }
- }
- else
- {
- (unsigned char)(image->data[x]) = ch;
- x++;
- if(x == old_bplin)//p.bplin)
- {
- int len = pcx_dump(image, new_image, 1);
- for(int t = 0; t < N_PLANES; t++)
- fwrite(new_image, len, 1, f1);
- x = plane;
- y++;
- }
- else
- if(!(x % old_bplin))//p.bplin))
- x -= shift;
-
- }
- }
- delete image;
- delete new_image;
- fclose(f);
- fclose(f1);
- return 1;
- }
- ///////////////////////// Demo code ////////////////////////
- /*
- #include <iostream.h>
- #include "dir.h"
- void main( int argc, char *argv[] )
- {
- char src_name[MAXPATH];
- char dest_name[MAXPATH];
-
- if(argc < 3)
- {
- cout << " ██████████████████████ FREEWARE █████████████████\n";
- cout << " ██ ██\n";
- cout << " ██ B&W Utility. (C) Stepan S. Vartanov, 1994. ██\n";
- cout << " ██ ██\n";
- cout << " █████████████████████████████████████████████████\n";
- cout << "╔═══════════════════════════════════════════════════════════════╗\n";
- cout << "║ Task: Color to B&W PCX files conversion ║\n";
- cout << "║ Usage: b&w.exe <src file > <result> <pattern> ║\n";
- cout << "║ Example: b&w.exe color.pcx bw.pcx ║\n";
- cout << "║ b&w.exe color.pcx bw.pcx 1000111101010101 ║\n";
- cout << "║ file masks (*.pcx) does not supported ║\n";
- cout << "║ Pattern determines, which of 16 colors should be black (0) ║\n";
- cout << "║ and which white (1) ║\n";
- cout << "╚═══════════════════════════════════════════════════════════════╝\n";
- return;
- }
- if(argc >= 3)
- {
- strcpy(src_name, argv[1]);
- strcpy(dest_name, argv[2]);
- }
- if(argc == 4)
- {
- if(strlen(argv[3]) < 16)
- {
- cout << "Use 16 colors in mask\n";
- return;
- }
- for(int i = 0; i < 16; i++)
- {
- if(argv[3][i] == '0')
- memset(pattern[i], 255, 8);
- else
- memset(pattern[i], 0, 8);
- }
- }
-
- if(!strcmp(dest_name, src_name))
- {
- pcx_col_to_bw(src_name, "tmp____u.pcy");
- unlink(src_name);
- rename("tmp____u.pcy", src_name);
- }
- else
- pcx_col_to_bw(src_name, dest_name);
-
- cout << "KNOW-HOW 5.0,Software development kit,Library in source codes (Borland C++ 3.x)\n";
- cout << "█████████████████████████████████████████████████████████████████████████████\n";
- cout << ">>> KNOW-HOW.Interface: GUI, LJ fonts(SFP) screen output, PCX, multiple over-\n";
- cout << "lapped windows, Scripts and macroses. DOS\n";
- cout << ">>> KNOW-HOW.DEBUGGER: For any situations, including hang-up. DOS\n";
- cout << ">>> KNOW_HOW.GRAPHICS: Using common code for any graphics library. Now it is\n";
- cout << "realized now for BGI and Windows GDI. Scrolling, Zooming, reflection of image,\n";
- cout << "rotations and complex rotations. Rotated and filled BGI fonts. DOS, WINDOWS\n";
- cout << ">>> KNOW-HOW.SLANG: Basic-like language. Multy-file programs, FOR, IF and so\n";
- cout << "on operators. User could derive from Slang the child class with new operators\n";
- cout << "to access functions of his concrete package. DOS, WINDOWS\n";
- cout << ">>> KNOW-HOW.VECTOR: Vector pictures editor. Simple KNOW-HOW.GRAPHICS\n";
- cout << "interpreter in DOS or Windows. Powerfull tool for maketing BGI, GDI and so on.\n";
- cout << ">>> KNOW-HOW.DRAW: PCX pictures editor. All standart image-editing functions.\n";
- cout << ">>> KNOW-HOW.PRINT: Create on disk virtual screen of any size, show, scroll\n";
- cout << "on screen or print on different printers with any deformation. DOS.\n";
- cout << ">>> KNOW-HOW.DATASHELL: Shell for Paradox Engine 3.01 or any other database\n";
- cout << "engine. View and edit tables and querries in Paradox-like style. Multy-table\n";
- cout << "QBE querries. Print reports in user-defined form. DOS.\n";
- cout << ">>> KNOW-HOW.GRAF: Business and scientific diagrams. Line, Markers,\n";
- cout << "Line-and-markers, Bar, 3d-Bar, Stacked bar graphs... DOS, WINDOWS\n";
- }
-
- */